<?php

namespace yunj\app\admin\service\route\page;

use yunj\app\admin\enum\EnableLoginAuth;
use yunj\app\admin\enum\route\RequestMethod;
use yunj\app\admin\enum\route\RouteDataType;
use yunj\app\admin\enum\State;
use yunj\app\admin\model\Model;
use yunj\app\admin\service\route\RouteRequestService;
use yunj\app\admin\service\route\RouteService;
use yunj\app\admin\validate\route\RouteValidate;
use yunj\core\builder\YunjForm;

class RouteAddService extends RouteFormService {

    // 添加类型
    private $type;

    /**
     * 添加类型对象
     * @var RouteDataType $typeObj
     */
    private $typeObj;

    // 添加类型对应的父类型
    private $parentType;

    // 添加类型对应的父类型id
    private $parentId;

    // 添加类型对应的父类型数据
    private $parentData;

    public function __construct() {
        // 添加类型
        if (($type = request()->param('type')) && RouteDataType::isValue($type)) {
            $this->type = $type;
            $this->typeObj = RouteDataType::byValue($type);
        } else {
            throw new \RuntimeException('非法请求');
        }

        // 父类型数据
        if (
            ($idParam = request()->param('id')) && strstr($idParam, '_')
            && (list($parentType, $parentId) = explode('_', $idParam))
            && $parentType && $parentId && in_array($parentType, [RouteDataType::GROUP, RouteDataType::ROUTE])
        ) {
            if ($parentType == RouteDataType::ROUTE) {
                $parentData = RouteService::getValidRouteDataById($parentId);
            } else {
                /** @var RouteDataType $parentTypeObj */
                $parentTypeObj = RouteDataType::byValue($parentType);
                $parentData = $parentTypeObj->getModel()->getOwnRowToArray([
                    ['id', '=', $parentId],
                    ['state', '=', State::NORMAL],
                ], ['*']);
            }
            if ($parentData) {
                $this->parentType = $parentType;
                $this->parentId = $parentId;
                $this->parentData = $parentData;
            }
        }

        // 路由请求项必传id
        if ($type == RouteDataType::REQUEST && !$this->parentData) {
            throw new \RuntimeException('请求异常，请刷新页面后重试');
        }
    }

    /**
     * @return mixed|string
     */
    public function getType() {
        return $this->type;
    }

    /**
     * @return RouteDataType
     */
    public function getTypeObj(): RouteDataType {
        return $this->typeObj;
    }

    /**
     * @return mixed|string
     */
    public function getParentId() {
        return $this->parentId;
    }

    /**
     * @return array|mixed
     */
    public function getParentData() {
        return $this->parentData;
    }

    public function getBuilder(): YunjForm {
        $args = [
            'field' => function (YunjForm $builder) {
                return $this->getBuilderField($builder);
            },
            'validate' => RouteValidate::class,
            'button' => function ($builder) {
                return $this->parentData ? ['reset', 'submit'] : ['clear', 'submit'];
            },
            'submit' => function (YunjForm $builder, array $data) {
                // 触发设置保存前事件
                event('AdminRouteSaveBefore', ['isEdit' => false, 'loadValues' => [], 'data' => $data]);
                try {
                    /** @var Model $model */
                    $model = $data['model'];
                    $model->addRow($data['dbData']);
                    // 清理缓存
                    RouteRequestService::clearCache();
                    // 路由重置
                    RouteService::reset();
                    return success_json(["reload" => true]);
                } catch (\Throwable $e) {
                    log_exception($e);
                    return error_json('新增失败');
                }
            }
        ];
        return YF('RouteAddForm', $args);
    }

    // 获取构建器字段配置
    private function getBuilderField(YunjForm $builder): array {
        $field = [];
        switch ($this->type) {
            case RouteDataType::GROUP:
                // 添加分组
                $field = [
                        'line' => ['type' => 'line', 'title' => '添加分组'],
                    ] + $this->getGroupCommonField();
                if ($this->parentData) {
                    $groupInfo = "父级分组：【名称】" . $this->parentData['name'];
                    if ($desc = $this->parentData['desc']) {
                        $groupInfo .= "【描述】" . $desc;
                    }
                    array_insert($field, [
                        'group_info' => ['type' => 'txt', 'desc' => $groupInfo]
                    ], 'line');
                }
                break;
            case RouteDataType::ROUTE:
                // 添加路由
                $field = [
                        'line' => ['type' => 'line', 'title' => '添加路由'],
                    ] + $this->getRouteCommonField();
                if ($this->parentData) {
                    $groupInfo = "父级分组：【名称】" . $this->parentData['name'];
                    if ($desc = $this->parentData['desc']) {
                        $groupInfo .= "【描述】" . $desc;
                    }
                    array_insert($field, [
                        'group_info' => ['type' => 'txt', 'desc' => $groupInfo]
                    ], 'line');
                }
                break;
            case RouteDataType::REQUEST:
                // 添加路由请求
                $routeInfo = "路由：【Uri】" . $this->parentData['base_url'] . "【地址】" . $this->parentData['route'];
                if ($desc = $this->parentData['desc']) {
                    $routeInfo .= "【描述】" . $desc;
                }
                $field = [
                        'route_info' => ['type' => 'txt', 'desc' => $routeInfo],
                        'line' => ['type' => 'line', 'title' => '添加路由请求'],
                    ] + $this->getRequestCommonField();
                break;
        }
        // 设置栅格布局
        foreach ($field as &$v) {
            $v['grid'] = [12, "6 l3 r3", "6 l3 r3"];
        }
        return $field;
    }

}